#include "Algebre/Matrice3x3.hpp"
#include "Algebre/MatriceGL3.hpp"

#include "Utils/Erreur.hpp"

#include <iostream>

#include <boost/numeric/ublas/lu.hpp>

using namespace std;
using namespace boost::numeric::ublas;

template< class T >
bool inverseMatrice( const matrix< T >& in, matrix< T >& out )
{
    typedef permutation_matrix< size_t > pmatrix;

    matrix< T > A( in );

    pmatrix pm( A.size1() );

    int res( lu_factorize( A, pm ) );
    if ( res != 0 )
        return false;

    out.assign( identity_matrix< T >( A.size1() ) );

    lu_substitute( A, pm, out );

    return true;
}

int main()
{
  VecteurU yp(1, 0, 1), xp(0, 1, 0), crap(1, 1, 1);
  Matrice3x3 id, autre(xp, yp, xp^yp);

  MatriceGL3 inversible( Vecteur( 0., -2., 0. ), Vecteur( 1., 0., 0. ), Vecteur( 0., 0., 1.) ), inverse;

  cout << id << "=> déterminant = " << id.determinant() << endl;
  cout << inversible << "=> déterminant = "
       << inversible.determinant() << endl << endl;

  cout << inversible << "=> inverse =" << endl << inversible.inverse() << endl;

  if ( inverseMatrice( inversible, inverse ) )
       cout << " ou " << endl << inverse << endl;

  cout << " multiplication =" << endl
       << inversible * inverse << endl;

  Vecteur a( 3., 0., 4. );

  cout << a << " -> " << (inversible * a) << endl;

  cout << "Test de comatrice :" << endl;
  cout << Matrice3x3( 1. ) << endl << "donne " << endl;  
  cout << Matrice3x3( 1. ) . comatrice() << endl;

  try
    {
      Matrice3x3 m( crap, xp, crap^xp );
    }
  catch (Erreur& e)
    {
      cerr << "Problème avec notre dernière matrice" << endl;
    }

  return 0;
}
